package de.slothsoft.commons.swing;

import java.util.ArrayList;
import java.util.List;

import javax.swing.table.AbstractTableModel;

public abstract class AbstractListTableModel<T> extends AbstractTableModel {

	private static final long serialVersionUID = 1L;

	private String[] columnNames;
	protected List<T> list;

	public AbstractListTableModel(String[] columnNames) {
		this(new ArrayList<T>(), columnNames);
	}

	public AbstractListTableModel(List<T> list, String[] columnNames) {
		assert list != null;
		assert columnNames != null;

		this.list = list;
		this.columnNames = columnNames;
	}

	protected abstract Object getProperty(T value, int column);

	@Override
	public int getRowCount() {
		return this.list.size();
	}

	@Override
	public String getColumnName(int column) {
		return this.columnNames[column];
	}

	@Override
	public int getColumnCount() {
		return this.columnNames.length;
	}

	@Override
	public Object getValueAt(int rowIndex, int columnIndex) {
		T value = getElement(rowIndex);
		return getProperty(value, columnIndex);
	}

	public T getElement(int rowIndex) {
		return this.list.get(rowIndex);
	}

	public void addEntry(T entry) {
		addEntry(this.list.size(), entry);
	}

	public void addEntry(int index, T entry) {
		this.list.add(index, entry);
		fireTableRowsInserted(index, index);
	}

	public void removeEntry(T entry) {
		int index = this.list.indexOf(entry);
		this.list.remove(entry);
		if (index >= 0) {
			fireTableRowsDeleted(index, index);
		}
	}

	public void setColumnNames(String[] columnNames) {
		this.columnNames = columnNames;
		fireTableStructureChanged();
	}

	public String[] getColumnNames() {
		return this.columnNames;
	}

	public List<T> getList() {
		return this.list;
	}

	public void setList(List<T> newList) {
		this.list = newList;
		fireTableDataChanged();
	}

}
